mapLatest()
, at its core, works like map()
: you give mapLatest()
a lambda
expression or other function type, and mapLatest()
invokes that lambda for
every upstream item and emits whatever the lambda returns.
map()
, however, is designed for fast operations. That is not always your use case.
For example, suppose that you have a search field, and searching involves
a database query or a Web service call. You want to show search results as
the user types, so you apply a debounce()
operator to a Flow
representing
the user input. But the user might type faster than the database or Web service
handles the search. In that case, once you get the updated search expression,
you want to cancel any outstanding search operation and start a new one.
That is what mapLatest()
is for.
The lambda expression can call suspend
functions, such as for I/O. If the
lambda expression evaluates to a value before the upstream Flow
emits something
new, whatever the lambda evaluates to is emitted downstream. However, if the
upstream Flow
does emit something while the lambda is still doing work,
the coroutine invoking the lambda expression is cancelled, and the lambda
is re-invoked with the new value.
In this sample, you will only see Result for 4
in the output. While the
debounce(250)
operator will emit values for both 3
and 4
, 4
will be
emitted before the mapLatest()
lambda completes its delay()
, so the 3
invocation of the lambda is cancelled. If you remove or comment out that delay(500)
call, though, you will see Result for 3
and Result for 4
.